package com.example.demo.service;

import com.example.demo.model.common.DeviceRenewalRequest;
import com.example.demo.model.common.DeviceRenewalResponse;
import com.example.demo.model.entity.CardDetail;
import com.example.demo.model.common.RenewalRequest;
import com.example.demo.model.entity.CardInfo;
import com.example.demo.model.entity.CardPackage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.Collections;
import java.util.UUID;

@Slf4j
@Service
public class DeviceRenewalService {

    @Autowired
    private IotCardService iotCardService;

    @Autowired
    private WechatCloudDBService cloudDBService;

    @Autowired
    private ObjectMapper objectMapper;

    @Transactional
    public DeviceRenewalResponse processRenewal(DeviceRenewalRequest request) {
        DeviceRenewalResponse response = new DeviceRenewalResponse();
        String queryResult = null;

        try {
            // 打印接收到的请求参数
            log.info("接收到设备续费请求参数: {}", request);

            // 1. 通过IMEI查询ICCID
            String deviceQuery = String.format("db.collection('devices').where({imei: '%s'}).get()", request.getImei());
            log.info("开始查询设备信息, IMEI: {}", request.getImei());

            try {
                queryResult = cloudDBService.executeQuery(deviceQuery);
                log.debug("云数据库返回原始数据: {}", queryResult);

                JsonNode deviceResult = objectMapper.readTree(queryResult);

                // 检查API调用是否成功
                if (deviceResult.has("errcode") && deviceResult.get("errcode").asInt() != 0) {
                    throw new RuntimeException("云数据库查询失败: " + deviceResult.get("errmsg").asText());
                }

                // 检查data节点
                JsonNode dataNode = deviceResult.get("data");
                if (dataNode == null || !dataNode.isArray() || dataNode.size() == 0) {
                    throw new RuntimeException("未找到设备信息，IMEI: " + request.getImei());
                }

                // 获取第一条设备记录并解析JSON字符串
                JsonNode deviceNode = objectMapper.readTree(dataNode.get(0).asText());
                log.debug("获取到的设备信息: {}", deviceNode);

                // 检查和获取ICCID
                JsonNode iccidNode = deviceNode.get("iccid");
                if (iccidNode == null || iccidNode.isNull()) {
                    throw new RuntimeException("设备ICCID信息不存在");
                }

                String iccid = iccidNode.asText();
                if (iccid.isEmpty()) {
                    throw new RuntimeException("设备ICCID不能为空");
                }

                log.info("成功获取设备ICCID: {}", iccid);

                // 2. 查询卡详情
                List<CardInfo> cardInfoList = iotCardService.queryCardInfoList(List.of(iccid));
                if (cardInfoList.isEmpty()) {
                    throw new RuntimeException("未找到SIM卡信息");
                }

                CardInfo cardInfo = cardInfoList.get(0);
                LocalDateTime expirationDate = parseExpirationDate(cardInfo.getDueExpireTime());

                // 3. 检查用户余额
                String userQuery = String.format(
                        "db.collection('users').doc('%s').get()",
                        request.getUserId()
                );

                String userQueryResult = cloudDBService.executeQuery(userQuery);
                JsonNode userResult = objectMapper.readTree(userQueryResult);
                JsonNode userData = userResult.get("data");

                if (userData == null || !userData.isArray() || userData.size() == 0) {
                    throw new RuntimeException("未找到用户信息");
                }

                // 解析用户数据中的JSON字符串
                JsonNode userNode = objectMapper.readTree(userData.get(0).asText());
                JsonNode balanceNode = userNode.get("balance");

                if (balanceNode == null || balanceNode.isNull()) {
                    throw new RuntimeException("用户余额信息不存在");
                }

                double userBalance = balanceNode.asDouble();
                if (userBalance < request.getTotalPrice()) {
                    throw new RuntimeException(String.format("余额不足，当前余额: %.2f, 需要金额: %.2f",
                            userBalance, request.getTotalPrice()));
                }

                // 4. 处理续费
                LocalDateTime now = LocalDateTime.now();
                boolean isExpired = expirationDate.isBefore(now);
                String orderStatus;
                String outTradeNo = "device_renewal_" + System.currentTimeMillis();

                try {
                    // 确定订单状态
                    if (isExpired) {
                        // 过期卡片，查询卡套餐信息
                        orderStatus = "PENDING_REVIEW";
                        log.info("卡片已过期，查询卡套餐信息，订单状态设为待审核，当前到期时间: {}", expirationDate);

                        // 查询卡套餐信息
                        List<CardPackage> cardPackages = iotCardService.queryCardPackage(List.of(iccid));
                        if (cardPackages.isEmpty()) {
                            throw new RuntimeException("未找到SIM卡套餐信息");
                        }

                        CardPackage cardPackage = cardPackages.get(0);

                        // 创建订单记录，包含套餐信息
                        createOrderRecordWithPackage(request, outTradeNo, orderStatus, cardPackage);
                    } else {
                        // 未过期卡片，订单状态为已完成
                        orderStatus = "COMPLETED";
                        log.info("卡片未过期，订单状态设为已完成。当前到期时间: {}", expirationDate);

                        // 创建订单记录，不含套餐信息
                        createOrderRecord(request, outTradeNo, orderStatus);
                    }
                } catch (Exception e) {
                    log.error("处理订单状态失败", e);
                    throw new RuntimeException("处理订单状态失败: " + e.getMessage());
                }

                // 5. 创建订单记录
                try {
                    createOrderRecord(request, outTradeNo, orderStatus);
                } catch (Exception e) {
                    log.error("创建订单记录失败", e);
                    throw new RuntimeException("创建订单记录失败: " + e.getMessage());
                }

                // 6. 如果是未过期状态，添加消费记录并扣除用户余额
                if (!isExpired) {
                    // 创建消费记录
                    try {
                        createTransactionRecord(request, outTradeNo);
                    } catch (Exception e) {
                        log.error("创建消费记录失败", e);
                        throw new RuntimeException("创建消费记录失败: " + e.getMessage());
                    }

                    // 扣除用户余额
                    String updateBalanceQuery = String.format(
                            "db.collection('users').doc('%s').update({data:{balance: %.2f}})",
                            request.getUserId(),
                            userBalance - request.getTotalPrice()
                    );

                    try {
                        cloudDBService.executeUpdate(updateBalanceQuery);
                    } catch (Exception e) {
                        log.error("更新用户余额失败", e);
                        throw new RuntimeException("更新用户余额失败: " + e.getMessage());
                    }
                }

                // 7. 更新设备过期时间（仅对未过期设备）
                if (!isExpired) {
                    LocalDateTime newExpirationDate = calculateNewExpirationDate(
                            expirationDate,  // 未过期卡片使用当前到期时间作为基准
                            request.getSelectedPlan(),
                            request.getDuration()
                    );

                    String updateDeviceQuery = String.format(
                            "db.collection('devices').where({imei: '%s'}).update({" +
                                    "data: {expireDate: '%s'}" +
                                    "})",
                            request.getImei(),
                            newExpirationDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                    );

                    try {
                        cloudDBService.executeUpdate(updateDeviceQuery);
                        log.info("设备过期时间更新成功，新的过期时间: {}", newExpirationDate);

                        // 8. 设置响应信息
                        response.setSuccess(true);
                        response.setMessage("续费成功");
                        response.setRemainingBalance(userBalance - request.getTotalPrice());
                        response.setNewExpirationDate(newExpirationDate.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                    } catch (Exception e) {
                        log.error("更新设备过期时间失败", e);
                        throw new RuntimeException("更新设备过期时间失败: " + e.getMessage());
                    }
                } else {
                    // 对于过期卡片，返回待审核状态
                    response.setSuccess(true);
                    response.setMessage("续费请求已提交，等待审核");
                    response.setRemainingBalance(userBalance);
                    response.setNewExpirationDate(expirationDate.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                }

            } catch (Exception e) {
                log.error("解析设备信息失败, 原始响应: {}", queryResult, e);
                throw new RuntimeException("处理设备信息失败: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("续费处理失败", e);
            response.setSuccess(false);
            response.setMessage(e.getMessage());
        }

        return response;
    }

    // 创建订单记录
    private void createOrderRecord(DeviceRenewalRequest request, String outTradeNo, String status) {
        LocalDateTime now = LocalDateTime.now();
        String formattedDateTime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        String addOrderQuery = String.format(
                "db.collection('orders').add({" +
                        "data: {" +
                        "  _id: '%s'," +
                        "  _openid: '%s'," +
                        "  createdAt: '%s'," +
                        "  deviceName: '%s'," +
                        "  imei: '%s'," +
                        "  outTradeNo: '%s'," +
                        "  status: '%s'," +
                        "  type: 'DEVICE_RENEWAL'," +
                        "  userId: '%s'" +
                        "}" +
                        "})",
                UUID.randomUUID().toString().replace("-", ""),
                request.getOpenid(),
                formattedDateTime,
                request.getDeviceName(),
                request.getImei(),
                outTradeNo,
                status,
                request.getUserId()
        );

        log.info("创建订单记录: {}", addOrderQuery);
        cloudDBService.executeAdd(addOrderQuery);
    }

    // 创建消费记录
    private void createTransactionRecord(DeviceRenewalRequest request, String outTradeNo) {
        LocalDateTime now = LocalDateTime.now();
        String formattedDateTime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        String addTransactionQuery = String.format(
                "db.collection('transactionRecords').add({" +
                        "data: {" +
                        "  _id: '%s'," +
                        "  _openid: '%s'," +
                        "  amount: %.2f," +
                        "  createdAt: '%s'," +
                        "  outTradeNo: '%s'," +
                        "  type: 'DEVICE_RENEWAL'," +
                        "  userId: '%s'" +
                        "}" +
                        "})",
                UUID.randomUUID().toString().replace("-", ""),
                request.getOpenid(),
                request.getTotalPrice(),
                formattedDateTime,
                outTradeNo,
                request.getUserId()
        );

        log.info("创建消费记录: {}", addTransactionQuery);
        cloudDBService.executeAdd(addTransactionQuery);
    }

    private LocalDateTime parseExpirationDate(String dateStr) {
        try {
            // 首先尝试解析完整的日期时间格式
            return LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        } catch (DateTimeParseException e) {
            // 如果失败，说明可能是只有日期，没有时间
            // 将日期转换为当天的23:59:59
            return LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE)
                    .atTime(23, 59, 59);
        }
    }

    private LocalDateTime calculateNewExpirationDate(LocalDateTime baseDate, String planType, int duration) {
        return switch (planType) {
            case "daily" -> baseDate.plusDays(duration);
            case "monthly" -> baseDate.plusMonths(duration);
            case "yearly" -> baseDate.plusYears(duration);
            default -> throw new IllegalArgumentException("Invalid plan type");
        };
    }

    private String getPlanPackageId(String planType) {
        return switch (planType) {
            case "daily" -> "DAILY_PACKAGE_ID";
            case "monthly" -> "MONTHLY_PACKAGE_ID";
            case "yearly" -> "YEARLY_PACKAGE_ID";
            default -> throw new IllegalArgumentException("Invalid plan type");
        };
    }

    private String getPlanPacketId(String planType) {
        return switch (planType) {
            case "daily" -> "DAILY_PACKET_ID";
            case "monthly" -> "MONTHLY_PACKET_ID";
            case "yearly" -> "YEARLY_PACKET_ID";
            default -> throw new IllegalArgumentException("Invalid plan type");
        };
    }

    // 创建包含套餐信息的订单记录
    private void createOrderRecordWithPackage(DeviceRenewalRequest request, String outTradeNo, String status, CardPackage cardPackage) {
        LocalDateTime now = LocalDateTime.now();
        String formattedDateTime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        String addOrderQuery = String.format(
                "db.collection('orders').add({" +
                        "data: {" +
                        "  _id: '%s'," +
                        "  _openid: '%s'," +
                        "  createdAt: '%s'," +
                        "  deviceName: '%s'," +
                        "  imei: '%s'," +
                        "  outTradeNo: '%s'," +
                        "  status: '%s'," +
                        "  type: 'DEVICE_RENEWAL'," +
                        "  userId: '%s'," +
                        "  packetId: '%s'," +
                        "  validateType: %d," +
                        "  packageId: '%s'," +
                        "  packageName: '%s'," +
                        "  packetName: '%s'" +
                        "}" +
                        "})",
                UUID.randomUUID().toString().replace("-", ""),
                request.getOpenid(),
                formattedDateTime,
                request.getDeviceName(),
                request.getImei(),
                outTradeNo,
                status,
                request.getUserId(),
                cardPackage.getPacketId(),
                cardPackage.getValidateType(),
                cardPackage.getPackageId(),
                cardPackage.getPackageName(),
                cardPackage.getPacketName()
        );

        log.info("创建包含套餐信息的订单记录: {}", addOrderQuery);
        cloudDBService.executeAdd(addOrderQuery);
    }
}